﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace BawangMemo.BackendModels
{
    class Program
    {
        private static void CreateXML(string path)
        {
            using (XmlWriter writer = XmlWriter.Create(path))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("courses");
                writer.WriteEndElement();
                writer.Flush();
                writer.Close();
            }
        }

        private static void TestBuildCourse()
        {
            List<BookInfo> books = BookRepository.GetBookList();
            BookInfo bi = null;
            foreach (BookInfo bookInfo in books)
            {
                Console.WriteLine(bookInfo.BookName);
                if (bookInfo.BookName.Equals("GRE红宝书-丰富版"))
                {
                    bi = bookInfo;
                }
            }
            if (bi == null)
            {
                Console.WriteLine("cannot found book");
                Console.ReadLine();
                return;
            }

            string courseName = "中文_测试";
            if (CourseRepository.hasCourseName(courseName))
                courseName += "3";

            try
            {
                CourseRepository.CreateCourse(courseName, bi.BookPath, WordOrder.Reversal, 50);
            }
            catch (ApplicationException ae)
            {
                Console.WriteLine(ae.Message);
                return;
            }

            List<CourseInfo> courseInfos = CourseRepository.ListCourses();

            foreach (CourseInfo ci in courseInfos)
            {
                if (ci.CourseName.Equals(courseName))
                {
                    Console.WriteLine("Course [{0}] built.", courseName);
                }
            }
        }

        private static void TestLoadCourse()
        {
            foreach (CourseInfo courseInfo in CourseRepository.ListCourses())
            {
                CourseWrapper cw = CourseRepository.LoadCourse(courseInfo.CourseName);
                var wordList = cw.WordList;
                Console.WriteLine("Course {0} loaded.", cw.CourseName);
                Console.WriteLine("Word Count = {0}.", wordList.Count);
                foreach (int index in new int[] { 10, 100, 5000, 431, 8000 })
                {
                    WordWrapper ww = wordList[index];
                    WordCard wc = ww.GetWordCard();
                    Console.WriteLine(ww.Id + " " + wc.Spell + " " + wc.Meaning);
                    Console.ReadLine();
                }
            }
        }

        private static void TestRecite()
        {
            Random random = new Random();
            string courseName = CourseRepository.ListCourses()[0].CourseName;
            CourseWrapper cw = CourseRepository.LoadCourse(courseName);

            TestWordInfo(cw, new int[] { 1, 101, 201 });
            Console.ReadLine();

            int count = 0;
            cw.StartRecite();
            List<int> ids = new List<int>();
            while (cw.HasNextWordToRecite())
            {
                ++count;
                WordWrapper ww = cw.NextRecite;
                //WordCard wc = ww.GetWordCard();
                //Console.WriteLine(ww.Id + " " + wc.Spell + " " + wc.Meaning);
                Console.WriteLine(ww.Id);
                ids.Add(ww.Id);
                //int res = random.Next(4);
                int res = 3;
                cw.UserResponse(ww, res);
                Console.WriteLine("response: " + res);
            }
            Console.ReadLine();

            List<WordWrapper> list = WordRepository.LoadWordsFromCourse(cw);
            foreach (int index in ids)
            {
                WordWrapper ww = list[index - 1];
                Console.WriteLine(ww.WordInfo.Activated + " " + ww.WordInfo.Bucket + " " + ww.WordInfo.OldBucket +
                    " " + ww.WordInfo.MemCount + " " + ww.WordInfo.Proficiency);
            }
            Console.ReadLine();
        }

        private static void TestWordInfo(CourseWrapper cw, int[] point)
        {
            var list = WordRepository.LoadWordsFromCourse(cw);
            foreach (int index in point)
            {
                WordWrapper ww = list[index];
                Console.WriteLine(ww.WordInfo.Activated + " " + ww.WordInfo.Bucket + " " + ww.WordInfo.OldBucket +
                    " " + ww.WordInfo.MemCount + " " + ww.WordInfo.Proficiency);
            }
        }

        private static void TestTags()
        {
            string courseName = "霸王";
            for (int i = 1; i <= 10; i++)
                TagRepository.AddTag(courseName, i, "分类1");
            for (int i = 3; i <= 5; i++)
                TagRepository.RemoveTag(courseName, i, "分类1");
            CourseWrapper cw = CourseRepository.LoadCourse(courseName);
            var wordList = cw.WordList;
            for (int i = 6; i <= 13; i++)
                TagRepository.AddTag(wordList[i - 1], "分类2");
            for (int i = 8; i <= 10; i++)
                TagRepository.RemoveTag(wordList[i - 1], "分类1");
            foreach (string tag in TagRepository.ListAllTags(cw))
            {
                Console.Write(tag + " ");
            }
            Console.WriteLine();
            for (int i = 1; i <= 13; i++)
            {
                Console.Write(wordList[i - 1].Id + " tags:");
                foreach (string tag in wordList[i - 1].ListWordTags())
                {
                    Console.Write(" " + tag);
                }
                Console.WriteLine();
            }
            for (int i = 1; i <= 2; i++)
            {
                string tag = "分类" + i;
                Console.Write(tag + ":");
                foreach (WordWrapper wordWrapper in TagRepository.ListWordsOfTag(cw, tag))
                {
                    Console.Write(" " + wordWrapper.Id);
                }
                Console.WriteLine();
            }
        }

        private static void TestPrefix(string prefix)
        {
            string courseName = "霸王";
            if (!CourseRepository.hasCourseName(courseName))
            {
                CourseRepository.CreateCourse(courseName, "AppData/Book/GRE红宝书-丰富版.xml",
                    WordOrder.Sequential, 50);
            }
            CourseWrapper cw = CourseRepository.LoadCourse(courseName);
            foreach (WordWrapper ww in cw.ListPrefixWords(prefix))
            {
                Console.WriteLine(ww);
            }
        }

        private static void TestOld()
        {
            string courseName = "霸王";
            if (!CourseRepository.hasCourseName(courseName))
            {
                CourseRepository.CreateCourse(courseName, "AppData/Book/GRE红宝书-丰富版.xml",
                    WordOrder.Sequential, 50);
            }
            CourseWrapper cw = CourseRepository.LoadCourse(courseName);
            foreach (WordWrapper ww in cw.ListOldWords())
            {
                Console.WriteLine(ww);
            }
        }

        private static void TestGetBookList()
        {
            foreach (var a in BookRepository.GetBookList())
            {
                Console.WriteLine(a.BookName + ": " + a.BookPath + ", " + a.TagCategoryPath + ", " + a.TagDataPath);
            }
        }

        private static void TestBulkInsert()
        {
            CourseRepository.CreateCourse("bulk7", @"AppData\Book\GRE红宝书-丰富版.xml", WordOrder.Sequential, 20);
        }

        static void Main(string[] args)
        {
            //TestBuildCourse();
            //TestLoadCourse();
            //TestRecite();
            //TestTags();
            //TestPrefix("aba");
            //TestOld();
            //TestGetBookList();
            //TestBulkInsert();
            TestRegex("  0a2bc我_是");
            Console.ReadLine();
        }

        public const string VALID_COURSE_NAME_PATTERN = @"^[\u4e00-\u9fa5a-zA-Z0-9_]+$";

        private static void TestRegex(string name)
        {
            Console.WriteLine (Regex.IsMatch(name, VALID_COURSE_NAME_PATTERN));
            //Regex r = new Regex(VALID_COURSE_NAME_PATTERN);
            //Match m = r.Match(name);
            //if (m.Success)
            //{
            //    Console.WriteLine(m.Index);
            //}
            //else
            //{
            //    Console.WriteLine("failed");
            //}
        }
    }
}

/*
            using (FileStream fs = new FileStream("serial.dat", FileMode.Create))
            using (BinaryWriter bw = new BinaryWriter(fs))
                for (int i = 0; i < n; i++)
                {
                    WordInfo wi = new WordInfo
                    {
                        WordId = i,
                        Proficiency = i + 1,
                        MemCount = i + 2,
                        OldBucket = i + 3,
                        Bucket = i + 4
                    };
                    bw.Write(DataAccess.ObjectToBytes(wi, Constants.WORD_INFO_SIZE));
                }
 */
/*
            using (FileStream fs = new FileStream("serial.dat", FileMode.Open))
            using (BinaryReader bw = new BinaryReader(fs))
                for (int i = n - 1; i >= 0; i--)
                {
                    fs.Seek(Constants.WORD_INFO_SIZE * i, SeekOrigin.Begin);
                    WordInfo wi = DataAccess.BytesToObject(bw.ReadBytes(Constants.WORD_INFO_SIZE)) as WordInfo;
                    if (wi.WordId != i || wi.Proficiency != i + 1 || wi.MemCount != i + 2 ||
                        wi.OldBucket != i + 3 || wi.Bucket != i + 4)
                    {
                        Console.WriteLine("Wrong at {0}", i);
                    }
                }
            int i = 100;
            using (FileStream fs = new FileStream("serial.dat", FileMode.Open))
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                fs.Seek(Constants.WORD_INFO_SIZE * i, SeekOrigin.Begin);
                WordInfo wi = new WordInfo
                {
                    WordId = i,
                    Proficiency = i - 1,
                    MemCount = i - 2,
                    OldBucket = i - 3,
                    Bucket = i - 4
                };
                bw.Write(DataAccess.ObjectToBytes(wi, Constants.WORD_INFO_SIZE));
            }
            using (FileStream fs = new FileStream("serial.dat", FileMode.Open))
            using (BinaryReader bw = new BinaryReader(fs))
                {
                    fs.Seek(Constants.WORD_INFO_SIZE * i, SeekOrigin.Begin);
                    WordInfo wi = DataAccess.BytesToObject(bw.ReadBytes(Constants.WORD_INFO_SIZE)) as WordInfo;
                    if (wi.WordId != i || wi.Proficiency != i - 1 || wi.MemCount != i - 2 ||
                        wi.OldBucket != i - 3 || wi.Bucket != i - 4)
                    {
                        Console.WriteLine("Wrong at {0}", i);
                    }
                }

            Console.WriteLine("OK");
 */
